#include <iostream>
#include <thread>

/*
    Every thread has to have an initial function, which is 
    where the new thread of execution begins. 
*/
void hello() {
    std::cout << "I am working in the hello ....\n";

    for(int i = 0; i < 100; i++) ;

    std::cout << "Hello Concurrent World\n";
}

/*
    For the initial thread in an application, this is main(),
    but for every other thread it's specified in the constructor
    of std::thread object - in this case, the std::thread object
    named t has the new function hello() as its initial funciton.
*/
int main() {
    std::cout << "The main thread is lauching ...\n";

    // After the new thread has been launched, the initial thread
    // continues execution. If it didn't wait for the new thread 
    // to finish, it would merrily continue to the end of main()
    // and thus end the program - possibly before the new thread
    // had had a chance to run.
    std::thread t(hello);

    std::cout << "Now I am still in the main()...\n";

    // This causes the calling thread to wait for the thread 
    // associated with the std::thread object.
    t.join();

    std::cout << "The main will end ... \n";

    return 0;
}